package com.mypack.bookStore.security;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.AuthorizationServiceException;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

public class ValidateCodeUsernamePasswordAuthenticationFilter extends
		UsernamePasswordAuthenticationFilter {
	private String userNameParameter="userName";
	private String passWordParameter="passWord";
	private String validateCodeParameter="validateCode";
	private String validateCodeSessionName="validateCode";
	
	/**
	 * 是否只接收Post方式提交的数据
	 */
	private boolean postOnly = true;
	
	/**
	 * 是否需要验证码
	 */
	private boolean checkValidateCode = true;
	
	/**
	 * 验证成功，跳转页面
	 * 注意：地址必须是/ 或者 http开头的URL地址
	 */
	private String successUrl = "/main";
	private String failureUrl = "/login";
	
	private void init() {
		//配置接收表单参数的名称 默认是j_username 和 j_password
		//可以在这里手工指定，也可以Spring配置中注入
		this.setUsernameParameter(userNameParameter);
		this.setPasswordParameter(passWordParameter);
		
		//验证成功，跳转的页面
		SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
		successHandler.setDefaultTargetUrl(successUrl);
		this.setAuthenticationSuccessHandler(successHandler);
		
		//验证失败
		SimpleUrlAuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
		failureHandler.setDefaultFailureUrl(failureUrl);
		this.setAuthenticationFailureHandler(failureHandler);
	}
	/**
	 * 尝试验证
	 */
	@Override
	public Authentication attemptAuthentication(HttpServletRequest request,
			HttpServletResponse response) throws AuthenticationException {
		//如果只接收post提交并且提交的是get方法时
		if(postOnly && !request.getMethod().equals("POST")){
			throw new AuthorizationServiceException("Authentication method not supported :"+request.getMethod());
		}
		//取用户名、密码前，设置编码格式
//		try {
//			request.setCharacterEncoding("UTF-8");
//		} catch (UnsupportedEncodingException e) {
//			e.printStackTrace();
//		}
		if(checkValidateCode){
			checkValidateCode(request);
		}
		String username=obtainUsername(request);
		String password=obtainPassword(request);
		UsernamePasswordAuthenticationToken authRequest=new UsernamePasswordAuthenticationToken(username, password);
		setDetails(request,authRequest);
		return this.getAuthenticationManager().authenticate(authRequest);
	}
	
	protected void checkValidateCode(HttpServletRequest request){
		String sessionValidateCode=obtainSessionValidateCode(request);
		String validateCodeParameter=obtainValidateCode(request);
		//验证码输入不能为空，不区分大小写
		if(StringUtils.isBlank(validateCodeParameter)||!sessionValidateCode.equalsIgnoreCase(validateCodeParameter)){
			throw new AuthenticationServiceException(messages.getMessage("validateCode.notEquals"));
		}
	}
	protected String obtainSessionValidateCode(HttpServletRequest request){
		Object sessionCode = request.getSession().getAttribute(validateCodeSessionName);
		return null==sessionCode?"":sessionCode.toString();
	}
	protected String obtainValidateCode(HttpServletRequest request){
		return request.getParameter(validateCodeParameter);
	}
	protected String obtainUsername(HttpServletRequest request){
		String parameter = request.getParameter(userNameParameter);
		return null==parameter?"":parameter.trim();
	}
	protected String obtainPassword(HttpServletRequest request){
		String parameter= request.getParameter(passWordParameter);
		return null==parameter?"":parameter;
	}
	public String getUserNameParameter() {
		return userNameParameter;
	}
	public void setUserNameParameter(String userNameParameter) {
		this.userNameParameter = userNameParameter;
	}
	public String getPassWordParameter() {
		return passWordParameter;
	}
	public void setPassWordParameter(String passWordParameter) {
		this.passWordParameter = passWordParameter;
	}
	public boolean isPostOnly() {
		return postOnly;
	}
	public void setPostOnly(boolean postOnly) {
		this.postOnly = postOnly;
	}
	public boolean isCheckValidateCode() {
		return checkValidateCode;
	}
	public void setCheckValidateCode(boolean checkValidateCode) {
		this.checkValidateCode = checkValidateCode;
	}
	public String getSuccessUrl() {
		return successUrl;
	}
	public void setSuccessUrl(String successUrl) {
		this.successUrl = successUrl;
	}
	public String getFailureUrl() {
		return failureUrl;
	}
	public void setFailureUrl(String failureUrl) {
		this.failureUrl = failureUrl;
	}
	
}
